import UIKit
import AVFoundation

public class CHPhotoCropViewController: UIViewController {
    private let imageView = UIImageView()
    private let cropBox = UIView()
    private let overlayView = UIView() // To dim areas outside crop box
    public var originalImage: UIImage?
    private var currentScale: CGFloat = 1.0
    private var lastScale: CGFloat = 1.0
    private var imageFrame: CGRect = .zero
    private var cropBW:CGFloat = 360
    private var cropBH:CGFloat = 180
    private var isSavePhotoLib:Bool = false
    var sucessClosureB:((_ image:UIImage,_ fileUrl:URL?) ->Void)?  //成功回调 照片
    var failClosureB:((_ failMsg:String) -> Void)? //失败回调
    public  override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupGesture()
    }
    
    /**
     @param  isSavePhotoLib 是否保存到相册 默认不保存
     @param cropBW 选择裁剪相册宽 ，
     @param cropBH 选择裁剪相册高
     @param originalImage 原始图片
     */
    public init(originalImage: UIImage,cropBW:CGFloat = 360,cropBH:CGFloat = 180,isSavePhotoLib:Bool =  false,successB:@escaping ((_ cropImage:UIImage,_ fileUrl:URL?)->Void),failB:@escaping ((_ failmsg:String)->Void)) {
        super.init(nibName: nil, bundle: nil)
        self.sucessClosureB = successB
        self.failClosureB = failB
        self.cropBW = cropBW
        self.cropBH = cropBH
        self.originalImage = originalImage
        self.isSavePhotoLib = isSavePhotoLib
        self.modalPresentationStyle = .fullScreen
    }
    
    public required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        view.backgroundColor = .black
        
        guard let originalImage = originalImage else { return }
        
        // Configure image view
        imageView.contentMode = .scaleAspectFit
        imageView.image = originalImage
        view.addSubview(imageView)
        imageView.frame = view.bounds
        
        // Calculate initial image frame
        imageFrame = AVMakeRect(aspectRatio: originalImage.size, insideRect: imageView.bounds)
        
        // Configure overlay
        overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        overlayView.isUserInteractionEnabled = false
        view.addSubview(overlayView)
        overlayView.frame = view.bounds
        
        // Configure crop box
        cropBox.layer.borderColor = UIColor.white.cgColor
        cropBox.layer.borderWidth = 2
        cropBox.backgroundColor = .clear
        cropBox.frame = CGRect(x: view.center.x - 150, y: view.center.y - 150, width: self.cropBW, height: self.cropBH)
        view.addSubview(cropBox)
        cropBox.center = self.view.center
        
        // Create a path for the overlay with a clear area where the crop box is
        updateOverlay()
        
        // Configure buttons
        let confirmButton = UIButton(type: .system)
        confirmButton.setTitle("确定裁剪", for: .normal)
        confirmButton.setTitleColor(.white, for: .normal)
        confirmButton.backgroundColor = UIColor.systemBlue
        confirmButton.layer.cornerRadius = 5
        confirmButton.addTarget(self, action: #selector(confirmCrop), for: .touchUpInside)
        if #available(iOS 11.0, *) {
            confirmButton.frame = CGRect(x: view.bounds.width - 120, y: view.safeAreaInsets.top + 60, width: 100, height: 40)
        } else {
            // Fallback on earlier versions
        }
        view.addSubview(confirmButton)
        
        let cancelButton = UIButton(type: .system)
        cancelButton.setTitle("取消", for: .normal)
        cancelButton.setTitleColor(.white, for: .normal)
        cancelButton.backgroundColor = UIColor.systemGray
        cancelButton.layer.cornerRadius = 5
        cancelButton.addTarget(self, action: #selector(cancel), for: .touchUpInside)
        if #available(iOS 11.0, *) {
            cancelButton.frame = CGRect(x: 20, y: view.safeAreaInsets.top + 60, width: 100, height:40)
        } else {
            // Fallback on earlier versions
        }
        view.addSubview(cancelButton)
    }
    
    private func updateOverlay() {
        let path = UIBezierPath(rect: overlayView.bounds)
        let clearPath = UIBezierPath(rect: cropBox.frame)
        path.append(clearPath)
        path.usesEvenOddFillRule = true
        
        let maskLayer = CAShapeLayer()
        maskLayer.path = path.cgPath
        maskLayer.fillRule = .evenOdd
        overlayView.layer.mask = maskLayer
    }
    
    private func setupGesture() {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        cropBox.addGestureRecognizer(panGesture)
        
        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(_:)))
        imageView.addGestureRecognizer(pinchGesture)
        imageView.isUserInteractionEnabled = true
    }
    
    @objc private func handlePinch(_ gesture: UIPinchGestureRecognizer) {
        if gesture.state == .began {
            lastScale = currentScale
        }
        
        if gesture.state == .began || gesture.state == .changed {
            currentScale = lastScale * gesture.scale
            currentScale = min(max(currentScale, 0.5), 3.0)
            imageView.transform = CGAffineTransform(scaleX: currentScale, y: currentScale)
        }
    }
    
    @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
        let translation = gesture.translation(in: view)
        
        var newCenter = CGPoint(
            x: cropBox.center.x + translation.x,
            y: cropBox.center.y + translation.y
        )
        
        // Keep crop box within bounds
        newCenter.x = min(max(newCenter.x, cropBox.bounds.width/2), view.bounds.width - cropBox.bounds.width/2)
        if #available(iOS 11.0, *) {
            newCenter.y = min(max(newCenter.y, cropBox.bounds.height/2 + view.safeAreaInsets.top), view.bounds.height - cropBox.bounds.height/2 - view.safeAreaInsets.bottom)
        } else {
            // Fallback on earlier versions
        }
        
        cropBox.center = newCenter
        gesture.setTranslation(.zero, in: view)
        
        updateOverlay()
    }
    
    @objc private func confirmCrop() {
        guard let image = originalImage else { return }
            
            // 1. 获取图片在ImageView中的实际显示frame（考虑aspectFit）
    
            let imageSize = image.size
            let imageFrame = AVMakeRect(aspectRatio: imageSize, insideRect: imageView.bounds)
            
            // 2. 计算缩放后的图片frame（考虑用户 pinch 缩放）
            let scaledImageWidth = imageFrame.width * currentScale
            let scaledImageHeight = imageFrame.height * currentScale
            let scaledImageFrame = CGRect(
                x: imageView.center.x - scaledImageWidth/2,
                y: imageView.center.y - scaledImageHeight/2,
                width: scaledImageWidth,
                height: scaledImageHeight
            )
            
            // 3. 计算裁剪框相对于缩放后图片的位置
            let cropBoxFrame = cropBox.frame
            
            // 4. 转换到图片原始坐标系
            let cropX = (cropBoxFrame.minX - scaledImageFrame.minX) * (imageSize.width / scaledImageFrame.width)
            let cropY = (cropBoxFrame.minY - scaledImageFrame.minY) * (imageSize.height / scaledImageFrame.height)
            let cropWidth = cropBoxFrame.width * (imageSize.width / scaledImageFrame.width)
            let cropHeight = cropBoxFrame.height * (imageSize.height / scaledImageFrame.height)
            
            // 5. 确保裁剪区域在图片范围内
            let boundedRect = CGRect(
                x: max(0, cropX),
                y: max(0, cropY),
                width: min(imageSize.width - cropX, cropWidth),
                height: min(imageSize.height - cropY, cropHeight)
            )
            
            // 6. 执行裁剪
            var resultImage:UIImage?
            if let croppedImage = image.cgImage?.cropping(to: boundedRect) {
                resultImage = UIImage(cgImage: croppedImage, scale: image.scale, orientation: image.imageOrientation)
                // 保存或处理裁剪后的图片
                if self.isSavePhotoLib == true{
                    UIImageWriteToSavedPhotosAlbum(resultImage!, nil, nil, nil)
                }
             
            }
        
        if resultImage == nil{
            self.dismiss(animated: false)
            self.failClosureB!("图片处理失败")
       
            return
        }
        if self.sucessClosureB != nil{
            self.dismiss(animated: false)
            self.sucessClosureB!(resultImage!, nil)
        }
        
        
       
    }
    
    @objc private func cancel() {
        dismiss(animated: true)
    }
}

